package com.sinosoft.tcmcp.system.aop;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;

import org.aspectj.lang.JoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.sinosoft.framework.core.common.utils.StringUtil;
import com.sinosoft.tcmcp.system.security.SecurityUtil;

/**
 * 服务切面
 * 针对服务中的增加和删除类方法调用之前的处理
 * @author xiaoxiong
 *
 */
public class ServiceAspect {

	private Logger logger = LoggerFactory.getLogger(ServiceAspect.class);
	
	private String username = null;	//	用户帐号
	
	/**
	 * 增加类方法拦截处理
	 * 被拦截的service方法的第一个参数必须是持久化实体类或实体类集合
	 * @param jp	切点
	 */
	@SuppressWarnings("unchecked")
	public void beforeAdd(JoinPoint jp){
		logger.info("开始执行切面方法[beforeAdd]拦截处理:" + jp.getSourceLocation());
		if(StringUtil.isBlank(username)) {	//	获取当前会话的用户帐号
			username = SecurityUtil.getUsername();
		}
		Object arg = jp.getArgs()[0];	//	获取增加类方法的参数
		if(arg instanceof List){
			List<Object> args = (List<Object>) arg;
			for(int i=0; i<args.size(); i++) {
				invokeMethod(args.get(i), "setCreater", String.class, username);	//	调用设置创建者函数给其赋值
				invokeMethod(args.get(i), "setCreatedate", Date.class, new Date());	//	调用设置创建日期函数给其赋值
			}
		}else{
			invokeMethod(arg, "setCreater", String.class, username);	//	调用设置创建者函数给其赋值
			invokeMethod(arg, "setCreatedate", Date.class, new Date());	//	调用设置创建日期函数给其赋值
		}
	}
	
	/**
	 * 更新类方法拦截处理
	 * @param jp	切点
	 */
	@SuppressWarnings("unchecked")
	public void beforeUpdate(JoinPoint jp) {
		logger.info("开始执行切面方法[beforeUpdate]拦截处理:beforeUpdate" + jp.getSourceLocation());
		if(StringUtil.isBlank(username)) {
			username = SecurityUtil.getUsername();
		}
		Object arg = jp.getArgs()[0];
		if(arg instanceof List){
			List<Object> args = (List<Object>) arg;
			for(int i=0; i<args.size(); i++) {
				invokeMethod(args.get(i), "setUpdater", String.class, username);	//	调用设置更新者函数给其赋值
				invokeMethod(args.get(i), "setUpdatedate", Date.class, new Date());	//	调用设置更新日期函数给其赋值
			}
		}else{
			invokeMethod(arg, "setUpdater", String.class, username);	//	调用设置更新者函数给其赋值
			invokeMethod(arg, "setUpdatedate", Date.class, new Date());	//	调用设置更新日期函数给其赋值
		}
	}
	
	/**
	 * 反射调用方法
	 * @param object	拥有方法的对象实例
	 * @param methodName	方法名称
	 * @param argsType	参数类型
	 * @param args	方法参数
	 */
	private void invokeMethod(Object object, String methodName, Class<?> argsType, Object... args){
		Method method = null;
		try {
			method = object.getClass().getMethod(methodName, argsType);
		} catch (NoSuchMethodException | SecurityException e) {
			e.printStackTrace();
		}
		try {
			method.invoke(object, args);
		} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
			e.printStackTrace();
		}
	}
}
